iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0
自我挑戰組

JavaScript 奇奇怪怪的核心觀念系列 第 13

(Day13) 函式基礎與參數介紹

  • 分享至 

  • xImage
  •  

前言

函式在即使非 JavaScript 的程式語言中是非常重要的一塊,我們會根據需求在函式中建立一系列動作,需要的時候便接呼叫對應函式,不管需求是執行 Ajax API ,或是隱藏、顯示畫面中某某區塊,都會將這些需求寫在函式中。

呼叫函式

呼叫函式的方法,使用函式名稱搭配小刮號 ()

function Fn1(){
	console.log('一般函式')
}
Fn1()

也可以在小刮號中寫入參數,參數會帶到函式中,而函式的參數只跟在函式中建立的變數一樣,他的作用域只存在於函式中。

function Fn1(num){
	console.log(num) //1
}
Fn1(1)
console.log(num) //num 

實做中常常看到在函式 return 某個值,而其實 return 的值會直接回傳在呼叫函式的方法中,這種方法常用在會要執行某些重複動作的需求上。

function Fn1(num){
	var sum = num + 10
	return sum 
}

console.log(Fn1(1) , Fn1(2)) //11, 12

arguments

上面有介紹到函式帶參數功能,關於參數也有一個特別的功能,就是 arguments

arguments 這個語法在函式建立時,他也會被一同建立,即使我們不需告變數、參數他也會存在於函式中,而 arguments 其實就是我們呼叫函式時,所有參數組和而成的 類陣列。

function Fn1(){
	console.log(arguments) //Arguments(3) [1, 2, 3, .... ]
}
Fn1(1,2,3)

什麼是類陣列呢?簡單來講就是一個類似陣列但不是陣列的東西,但是類陣列與陣列最大差異在於可以使用的方法 or 功能會有很大差異,因此我們來看一下範例:

var a = ['1', '2', '3'];
console.dir(a);

點開變數 a 中的 [[Prototype]] 底下都會是陣列中的方法(太長因此不全部截圖):

arguments 中的 [[Prototype]] 就只有:

可以看的出來類陣列和原始陣列中的方法相差十分多。

參數作用域

當我們參數名稱和函式外層變數相同時,看看花生神魔術

var name ='Ryder'
function Fn1(name){
	console.log(name) // Jack
}
Fn1('Jack')

結果會是以傳入參數為準。
那麼看看對參數使用 = 運算子賦予一個新的值看看結果如何:

function Fn1(name){
	name = 'Annie'
	console.log(name) // Annie
}
Fn1('Jack')

結果會發現參數的值確實可以更改,其實參數跟函式中變數的範圍練特性是差不多的,當內層有該參數時,就會優先指向內層參數。

ES6 預設參數

在 ES6 語法中有新增一個預設參數方法,只需在參數旁邊使用 = 運算子賦值,之後呼叫函式時,若沒帶上參數,到了函式中參數便會套上預設的值,但如果呼叫函式時,有帶上參數,便還是以帶上的參數為主,是一個十分方變的功能:

function Fn1(name = 'Annie'){
	return name
}
console.log(Fn1()) //Annie
console.log(Fn1('Jack')) //Jack

參數與物件傳參考

先前也有介紹到物件傳參考這個特性,當我們物件傳入參數時,他也會是傳參考, :

var obj1 = { name:'Ryder' }
function Fn1(item){
	item.name = 'Annie'
	console.log(item.name, obj1.name) // Annie , Annie
}
Fn1(obj1 )

範例中兩個物件的 name 屬性的值也都會改成 'Annie'
不過當我們只是傳入物件中的屬性時,結果並非是傳參考,而僅僅是傳值

var obj1 = { name:'Ryder' }
function Fn1(item){
	item = 'Annie'
	console.log(item, obj1.name) // Annie , Ryder
}
Fn1(obj1.name)

因此有使用 ES Lint 時,如果有試者修改參數的值,他都會跳出請不要直接修改參數的相關警告,這點就是避免物件傳參考特性發生錯誤。

函式分類

最後來說說函式的分類,在先前 陳述式 /表達式 中有根據建立方法不同,將函式分成:

  • 函示陳述式(具名函式)
  • 函式表達式(匿名函式)

但這其實是根據這段語法是表達式、陳述式來做區分,或者說函式有沒有名字來做分類的,在 ES6 新增箭頭函式後,一般會把函式分成三種:

  • 一般傳統函式(又可分為 具名函式、匿名函式)
function Fn1(){
	console.log('傳統具名')
}
Fn1() 

var Fn2 = function(){
	console.log('傳統匿名')
}
Fn2()
  • 立即函式(IIFE),一般都是以 匿名函式 寫成,雖然也可寫成具名函式,不過這種寫法很少看到:
(function(){
	console.log('立即函式')
})() 
  • ES6 新增的箭頭函式,箭頭函式一律都是匿名函式,設計上就無法使用具名函式寫成:
var Fn3 = ()=> {
	console.log('箭頭函式')
}
Fn3()

參考文獻

  • JavaScript 核心篇 (六角學院)

上一篇
(Day12) 物件,淺拷貝/深拷貝
下一篇
(Day14) 閉包 (Closure) 介紹
系列文
JavaScript 奇奇怪怪的核心觀念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言